package main

import (
	"context"
	"fmt"
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"

	"common-service/handler"
	"common-service/interceptors"
	"common-service/tools"

	pbBanner "common-service/proto/banner"

	"github.com/dtm-labs/client/workflow"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
	grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
	grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
	"golang.org/x/term"
	"google.golang.org/grpc"
)

// go build -o common-service.exe main.go

func main() {
	// 初始化ZapLogger
	tools.ZapLog = tools.InitLogger()
	defer tools.ZapLog.Sync()
	// 替换 gRPC 内部日志（可选）
	grpc_zap.ReplaceGrpcLoggerV2(tools.ZapLog)

	// 配置cookie && session
	store := cookie.NewStore([]byte("secret"))
	store.Options(sessions.Options{
		MaxAge:   7200,
		Path:     "/",
		HttpOnly: true,
	})

	//基于redis 存储session
	// store, err := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret"))
	// if err != nil {
	// 	fmt.Println("store", err.Error())
	// 	return
	// }

	// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// +++++++++++++++++++++++++ grpc 服务 +++++++++++++++++++++++++
	// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// tcp协议监听指定端口号
	// 判断容器、非容器部署
	// 容器部署的服务地址：0.0.0.0
	// 非容器部署的服务地址：使用配置文件中配置的具体
	serviceHost := tools.ServiceHost
	if tools.IsRunningInContainer() {
		serviceHost = "0.0.0.0"
	}
	lis, err := net.Listen("tcp", serviceHost+fmt.Sprintf(":%d", tools.ServicePort))
	if err != nil {
		tools.ZapLog.Fatal(fmt.Sprintf("failed to listen: %v", err))
	}

	// 创建JaegerTracer
	// jaegerTracer, closer, err := tools.NewJaegerTracer(tools.ServiceName, tools.JaegerAddr)
	// if err != nil {
	// 	log.Fatalf("Failed to create JaegerTracer: %v", err)
	// }
	// defer closer.Close()
	// log.Println("jaegerTracer =", jaegerTracer)

	// 创建拦截器链
	unaryInterceptors := grpc_middleware.ChainUnaryServer(
		// 异常恢复拦截器
		grpc_recovery.UnaryServerInterceptor(grpc_recovery.WithRecoveryHandlerContext(tools.RecoveryHandler)),

		// 请求捕获拦截器
		tools.RequestCaptureInterceptor,

		// 认证拦截器
		interceptors.AuthInterceptor(),

		// 日志拦截器（添加自定义字段）
		grpc_zap.UnaryServerInterceptor(tools.ZapLog, grpc_zap.WithMessageProducer(tools.CustomMessageProducer)),
	)

	streamInterceptors := grpc_middleware.ChainStreamServer(
		grpc_zap.StreamServerInterceptor(tools.ZapLog),
		grpc_recovery.StreamServerInterceptor(),
	)

	// 实例化gRPC服务
	srv := grpc.NewServer(
		// 加载jaegerTracer
		// grpc.UnaryInterceptor(
		// 	grpc_opentracing.UnaryServerInterceptor(grpc_opentracing.WithTracer(jaegerTracer)),
		// ),
		grpc.UnaryInterceptor(unaryInterceptors),
		grpc.StreamInterceptor(streamInterceptors),
	)

	// 注册 banner 服务
	pbBanner.RegisterBannerSrvServer(srv, new(handler.BannerHandler))

	// 初始化注册dtm 服务
	workflow.InitGrpc(tools.DtmGrpcServer, tools.ServiceHost+fmt.Sprintf(":%d", tools.ServicePort), srv)

	// log.Printf("grpc server listening at %v", lis.Addr())
	tools.ZapLog.Info(fmt.Sprintf("grpc server listening at %v", lis.Addr()))

	// -------------- 初始化 grpc client --------------
	// tools.InitGrpcClientConn()

	// 启动grpc服务协程
	go func() {
		if err := srv.Serve(lis); err != nil {
			tools.ZapLog.Fatal(fmt.Sprintf("failed to serve: %v", err))
		}
	}()

	// 创建用于通知关闭完成的通道
	shutdownComplete := make(chan struct{})

	// 设置信号监听
	sigChan := make(chan os.Signal, 1)

	// 捕获标准信号（Unix-like 系统和 Windows Ctrl+C）
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

	// 专门处理控制台关闭事件
	if term.IsTerminal(int(os.Stdin.Fd())) {
		go watchConsoleEvent(sigChan)
	}

	// 等待关闭信号
	go func() {
		sig := <-sigChan
		log.Printf("Received shutdown signal: %v", sig)

		// 执行优雅关闭
		gracefulShutdown(srv, shutdownComplete)
	}()

	// 等待关闭完成
	<-shutdownComplete

	// 注销服务
	switch tools.ServiceRegister {
	case "nacos": // nacos 服务注册与发现
	case "etcd": // etcd 服务注册与发现
	case "consul": // consul 服务注册与发现
		tools.ConsulService.DeregisterService(tools.ServiceName)
	}

	tools.ZapLog.Info("Server shutdown completed")
}

// 监控控制台关闭事件
func watchConsoleEvent(sigChan chan<- os.Signal) {
	// 创建控制台事件通道
	eventChan := make(chan os.Signal, 1)

	// 捕获控制台事件
	signal.Notify(eventChan, syscall.SIGTERM, syscall.SIGINT)

	for {
		sig := <-eventChan
		switch sig {
		case syscall.SIGTERM: // 控制台关闭事件
			log.Println("Detected console close event")
			sigChan <- os.Interrupt
			return
		case syscall.SIGINT: // Ctrl+C 事件
			log.Println("Detected Ctrl+C event")
			sigChan <- os.Interrupt
			return
		}
	}
}

// 执行优雅关闭
func gracefulShutdown(s *grpc.Server, shutdownComplete chan<- struct{}) {
	log.Println("Initiating graceful shutdown...")

	// 设置超时上下文
	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
	defer cancel()

	// 使用通道跟踪优雅停止完成
	gracefulDone := make(chan struct{})

	go func() {
		s.GracefulStop() // 阻塞直到所有RPC完成
		close(gracefulDone)
	}()

	// 等待优雅停止完成或超时
	select {
	case <-gracefulDone:
		log.Println("gRPC server gracefully stopped")
	case <-ctx.Done():
		log.Println("Graceful stop timed out, forcing shutdown")
		s.Stop() // 强制停止
	}

	// 执行其他清理工作（数据库连接等）
	// cleanupResources()

	// 通知主程序关闭完成
	close(shutdownComplete)
}
